#ifndef __XP__H__
#define __XP__H__

#include "big_integer.hpp"
#include <iostream>

#define N 500

typedef BIG_NUMBERS::uinteger_short_vector_ff XP;

/*********************************************************************
 *  Initialize XP from '\0'-terminated string of digits.
 *********************************************************************/
 XP XPinitDecimal(char s[]);

/*********************************************************************
 *  Print integer in decimal to standard output.
 *********************************************************************/
 void XPshowDecimal(XP a);

/*********************************************************************
 *  Allocate and return a random integer of <= n digits.
 *  Precondition: n <= NN.
 *********************************************************************/
 XP XPrand(int n);

/*********************************************************************
 *  Return 1 if a is odd, 0 otherwise.
 *  Precondition: Integer a has at most NN digits.
 *********************************************************************/
 int XPisOdd(XP a);

/*********************************************************************
 *  Return (a  < b).   
 *  Return (a == b).   
 *  Return (a  > b).     
 *  Precondition: Integers a and b have at most NN digits.
 *********************************************************************/
 int XPless(XP a, XP b);
 int XPeq(XP a, XP b);
 int XPgreater(XP a, XP b);

/*********************************************************************
 *  Return a + b.   
 *  Precondition: Integers a and b have at most 2N digits.
 *********************************************************************/
 XP XPadd(XP a, XP b);

/*********************************************************************
 *  Return a - b.   
 *  Precondition: Integers a and b have at most NN digits.
 *********************************************************************/
 XP XPsub(XP a, XP b);

/*********************************************************************
 *  Return a * b.   
 *  Precondition: Integers a and b have at most N digits.
 *********************************************************************/
 XP XPmul(XP a, XP b);

/*********************************************************************
 *  Return a / b.   
 *  Return a % b.   
 *  Precondition: Integer a has at most 2N digits;
 *                Integer b has at most NN digits.
 *********************************************************************/
 XP XPdiv(XP a, XP b);
 XP XPmod(XP a, XP b);


/*********************************************************************
 *  Return a ^ b mod n.   
 *  Precondition: Integers a, b, and n have at most N digits.
 *********************************************************************/
 XP XPrsa(XP a, XP b, XP n);


/* ---------------------------------------------------------------- */
/* --------------EVERYTHING BELOW IS OPTIONAL---------------------- */
/* ---------------------------------------------------------------- */

int XPisPrime(XP a);              // is prime
int XPisEven(XP a);               // (a % 2 == 0)
int XPisZero(XP a);               // (a == 0)
int XPisPositive(XP a);           // (a  > 0)
int XPdigits(XP a);               // number of digits (minus leading 0's)
XP  XPgcd(XP a, XP b);            // gcd(a, b)
XP  XPshortdiv(XP a, int b);      // a / b
int XPshortmod(XP a, int b);      // a % b

#endif // __XP__H__
